
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;

public class InterfaceShell {

    static File diretorioAtual = new File(System.getProperty("user.dir"));

    public static void main(String[] args) throws IOException {


        String linhaComando;
        BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
        ArrayList<String[]> history = new ArrayList<String[]>();
        ArrayList<String> special = new ArrayList<String>();

        special.add("history");
        //special.add("!!");
        special.add("cd");




        while (true) {
// le o que o usuario digitou
            System.out.print("jsh>");
            linhaComando = console.readLine();
            String words[];
            //ArrayList<String> command = new ArrayList<String>();

            words = linhaComando.split(" ");
            ArrayList<String> wordsl = new ArrayList<String>(Arrays.asList(words));
            boolean ult = false;
            if (words.length <= 0) {
            } else {
                if (words[0].charAt(0) == '!') {
                } else {
                    if (history.size() > 0) {


                        if (ew(words, history.get(history.size() - 1))) {
                            //System.out.println("são iguais");
                        } else {
                            history.add(words);
                        }
                    } else {
                        history.add(words);
                    }
                }
                execute(words, history, special);
            }
// se o usuario digitar Enter fica em loop
            if (linhaComando.equals("")) {
                continue;
            }
        }

    }

    static void execute(String[] words, ArrayList<String[]> history,
            ArrayList<String> special) throws IOException {
        ProcessBuilder pb;

        if (special.contains(words[0]) || words[0].charAt(0) == '!') {

            if (words[0].equals("history")) {
                for (int i = 0; i < history.size(); i++) {
                    System.out.print(" " + i + " ");
                    for (int j = 0; j < history.get(i).length; j++) {
                        System.out.print(history.get(i)[j] + " ");
                        //System.out.println(words.length);
                    }
                    System.out.println();
                }
            }

            if (words[0].charAt(0) == '!') {

                if (words[0].equals("!!")) {
                    //System.out.println("!! s");
                    //String [] w = history.get(history.size() - 1);
                    ArrayList<String> aw = new ArrayList<String>(Arrays.asList(history.get(history.size() - 1)));
                    for (int i = 1; i < words.length; i++) {
                        aw.add(words[i]);
                    }

                    words = new String[aw.size()];

                    for (int i = 0; i < aw.size(); i++) {
                        words[i] = aw.get(i);
                    }

                    execute(words, history, special);

                } else if (isNumeric(words[0].substring(1))) {
                    //System.out.println("É um número");

                    int ind = Integer.valueOf(words[0].substring(1));
                    if (ind >= 0 && ind < history.size()) {
                        //words=history.get(Character.getNumericValue(words[0].charAt(1)));

                        ArrayList<String> aw = new ArrayList<String>(Arrays.asList(history.get(Integer.valueOf(words[0].substring(1)))));
                        for (int i = 1; i < words.length; i++) {
                            aw.add(words[i]);
                        }

                        words = new String[aw.size()];

                        for (int i = 0; i < aw.size(); i++) {
                            words[i] = aw.get(i);
                        }

                        execute(words, history, special);
                    }

                }
            }


            if (words[0].equals("cd")) {


                diretorioAtual = new File(words[1]);
                //System.out.println(diretorioAtual.getPath());
            }
        } else {

            try {
                pb = new ProcessBuilder(words);
                pb.directory(diretorioAtual);
                //System.out.println(pb.directory().getPath());
                //System.out.println(diretorioAtual.getPath());
                Process pro = pb.start();

                InputStream is = pro.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);


                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);

                }
                br.close();
                //System.out.println(pro.getInputStream());



            } catch (IOException e) {
                System.out.println("Comando inválido.");
            }

        }

    }

    static boolean isNumeric(String word) {
        for (char w : word.toCharArray()) {
            if (Character.isDigit(w) == false) {
                return false;
            }
        }
        return true;
    }

    static boolean ew(String[] words, String[] aw) {

        if (words.length != aw.length) {
            return false;
        } else {
            for (int i = 0; i < words.length; i++) {
                if (words[i].equals(aw[i])) {
                } else {
                    return false;
                }
            }
        }

        return true;
    }
    /**
     * (1)desmembrar a entrada para obter o comando e os parametros (2)cria o
     * processo externo (objeto ProcessBuilder) (3)iniciar o processo externo
     * (4)obter o fluxo de saida (5)apresentar o conteudo que e ́ retornado pelo
     * comando
     */
}
